package com.turboconnard.display;

import java.util.Vector;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;

import com.turboconnard.data.Library;
import com.turboconnard.events.Event;
import com.turboconnard.events.EventDispatcher;
import com.turboconnard.events.EventListener;

public class Sprite extends EventDispatcher implements EventListener{
	public float width = 0;
	public float height = 0;
	public float depth = 0;
	
	public float x = 0;
	public float y = 0;
	public float z = 0;
	
	
	public float rotationX;
	public float rotationY;
	public float rotationZ;
	
	public Sprite parent;
	public boolean visible = true;
	public float alpha = 1;
	
	protected float _tRotationX = 0;
	protected float _tRotationY = 0;
	protected float _tRotationZ = 0;
	protected float _tY = 0;
	protected float _tX = 0;
	protected float _tZ = 0;
	
	private float _gtX;
	private float _gtY;
	private float _gtZ;
	private float _gtRotationX;
	private float _gtRotationY;
	private float _gtRotationZ;

	private Vector<Sprite> _nextDisplayList;
	private Vector<Sprite> _displayList;
	private Vector<Sprite> _displayRemove;
	protected Stage stage;
	protected Library library;
	private boolean autoAlpha = true;
	public Rect boundingBox;
	public boolean boundingBoxEnabled;
	protected Paint _paintBB;
	public Graphics graphics;
	
	
	public Sprite() {
		stage = Stage.getInstance();
		if(stage==null) stage = (Stage)this;
		
		Log.d("---------------------stage"," + " + stage);
		
		library = Library.getInstance();
		setDisplayList(new Vector<Sprite>());
		_nextDisplayList = new Vector<Sprite>();
		_displayRemove = new Vector<Sprite>();
		
		visible = true;
		graphics = new Graphics();
		boundingBox = new Rect(0,0,0,0);
		boundingBoxEnabled = false;
		_paintBB = new Paint();
		_paintBB.setARGB(255, 255, 0, 0);
		_paintBB.setStyle(Paint.Style.STROKE);
		
		x = 
		y = 
		_tX = 
		_tY = 
		_tRotationX =
		_tRotationY =
		_tRotationZ =
		_gtX = 
		_gtY = 
		_gtZ =
		_gtRotationX =
		_gtRotationY =
		_gtRotationZ =
		rotationX =
		rotationY =
		rotationZ = 0;
	}
	public Rect pBounding(){
		Rect v = new Rect(	(int)(_gtX+boundingBox.left),
				(int)(_gtY+boundingBox.top),
				(int)(_gtX+boundingBox.right),
				(int)(_gtY+boundingBox.bottom));
		return v;
		
	}
	public Boolean hitTest(Sprite pSprite){
		return pBounding().intersect(pSprite.pBounding());		
	}
	
	public void addChild(Sprite pSprite){
		if(_nextDisplayList.contains(pSprite)) return;
		pSprite.parent = this;
		_nextDisplayList.add(pSprite);
	}
	public void removeChild(Sprite pSprite){
		_displayRemove.add(pSprite);
	}
	public void removeAllChilds(){
		for (Sprite pSprite : getDisplayList()) {
			_displayRemove.add(pSprite);			
		}
	}
	public void update(){
		_update();
		for (Sprite s : getDisplayList()) {
		//	s.transform( _gtX,_gtY,_gtZ,_gtRotationX + rotationX,_gtRotationY + rotationY,_gtRotationZ + rotationZ);
			s.update();
		}
	}
	/*
	public void transform(float pX,float pY,float pZ,float pRotationX,float pRotationY,float pRotationZ) {
		_gtRotationX = pRotationX;
		_gtRotationY = pRotationY;
		_gtRotationZ = pRotationZ;
		
		float hyp = (float) Math.sqrt(x*x + y*y );
		double ang = Math.atan2(y,x);
		
		float xx = (float) Math.cos( ang + ( _gtRotation * Math.PI/180 ) )*hyp;
		float yy = (float) Math.sin( ang + ( _gtRotation * Math.PI/180 ) )*hyp;
		
		//_gtX = pX + xx;
		//_gtY = pY + yy;	
	}*/
	protected void _update() {
		
	}
	public Rect getGlobalBoundingBox(){
		Rect rect = new Rect();	
		return rect;
	}
	
	public void draw(GL10 gl){
		if(alpha <=0 || !visible) return;
		/*
		pCanvas.save();
		pCanvas.rotate(rotation);	
		_drawGraphics(pCanvas);
		*/
		gl.glPushMatrix();
			gl.glTranslatef(x*stage.correction, -y*stage.correction, z*stage.correction);
			gl.glRotatef(rotationX, 1,0,0);
			gl.glRotatef(rotationY, 0,1,0);
			gl.glRotatef(rotationZ, 0,0,1);
			_draw(gl);
			for (Sprite s : getDisplayList()) s.draw(gl);
		gl.glPopMatrix();
		/*
		if(boundingBoxEnabled){
			pCanvas.save();
			pCanvas.translate(x,y);
			pCanvas.rotate(-_gtRotation);
			pCanvas.drawRect(boundingBox, _paintBB);		
			pCanvas.restore();
		}*/
		/**
		 * remove pending childs
		 */
		if(getDisplayList().containsAll(_displayRemove)){
			getDisplayList().removeAll(_displayRemove);
			_displayRemove = new Vector<Sprite>();
		}	
		/**
		 * add pending childs
		 */
		if(_nextDisplayList.size()>0){
			getDisplayList().addAll(_nextDisplayList);
			_nextDisplayList = new Vector<Sprite>();
		}
			
	}
	protected void _drawGraphics(Canvas pCanvas) {
	//	graphics.draw(pCanvas);
	}
	protected void _draw(GL10 gl) {
		// TODO Auto-generated method stub
	}
	public void event(Event e){
		
	}

	public void setDisplayList(Vector<Sprite> _displayList) {
		this._displayList = _displayList;
	}
	public Vector<Sprite> getDisplayList() {
		return _displayList;
	}
	public void clear() {
		// TODO Auto-generated method stub
		_nextDisplayList = new Vector<Sprite>();
		_displayRemove = new Vector<Sprite>();
		_displayList = new Vector<Sprite>();
		visible = true;
	}
}
